package com.koron.css2.contractmanage.impl;

import com.koron.css2.ServerInterface;
import com.koron.css2.baseConfig.bean.MeterBoreBean;
import com.koron.css2.baseConfig.mapper.ConfigMapper;
import com.koron.css2.baseConfig.mapper.MeterBoreMapper;
import com.koron.css2.contractmanage.Enum.ContractStatusEnum;
import com.koron.css2.contractmanage.Enum.ContractTypeEnum;
import com.koron.css2.contractmanage.bean.ContractManageAddBean;
import com.koron.css2.contractmanage.bean.ContractManageBean;
import com.koron.css2.contractmanage.bean.PubCompanyContractBean;
import com.koron.css2.contractmanage.exception.ContractException;
import com.koron.css2.contractmanage.mapper.ContractManageMapper;
import com.koron.css2.contractmanage.mapper.PubCompanyContractMapper;
import com.koron.css2.contractmanage.service.EcContratServiceImpl;
import com.koron.css2.contractmanage.util.EcConstant;
import com.koron.css2.contractmanage.vo.UserInfoVO;
import com.koron.css2.serviceManage.bean.RequestBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.css2.serviceManage.utils.JsonUtils;
import com.koron.util.Constant;
import com.koron.util.Tools;
import net.qiyuesuo.v3sdk.model.common.DetailContract;
import net.qiyuesuo.v3sdk.utils.SdkResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 新增合同信息
 *
 */
public class ContractManageAdd implements ServerInterface {

    private EcContratServiceImpl ecContratService = new EcContratServiceImpl();


    @Override
    public MessageBean<?> exec(SessionFactory factory, UserInfoBean userInfo, RequestBean req) {
        try {
            ContractManageAddBean contractManageAddBean = JsonUtils.objectToPojoIgnoreNone(req.getData(), ContractManageAddBean.class);
            ContractManageMapper contractManageMapper = factory.getMapper(ContractManageMapper.class);
            PubCompanyContractMapper pubCompanyContractMapper = factory.getMapper(PubCompanyContractMapper.class, "_default");
            MeterBoreMapper meterBoreMapper = factory.getMapper(MeterBoreMapper.class);
            ConfigMapper configMapper = factory.getMapper(ConfigMapper.class);
            String ecPeCategoryId = configMapper.getConfigValueByNameOn(EcConstant.EC_PE_CATEGORYID);
            String ecCoCategoryId = configMapper.getConfigValueByNameOn(EcConstant.EC_CO_CATEGORYID);
            String ecCompanyName = configMapper.getConfigValueByNameOn(EcConstant.EC_COMPANY_NAME);

            List<ContractManageBean> contractManageBeanList = contractManageAddBean.getContractManageBeanList();
            checkContractManageQuery(contractManageBeanList, ecPeCategoryId, ecCoCategoryId, contractManageMapper, userInfo);

            // 合同类型
            String contractType = contractManageAddBean.getContractType();
            //插入普通施工合同
            if (ContractTypeEnum.CONTRACT_TYPE_3.getContractType().equals(contractType)) {
                ContractManageBean contractManageBean = contractManageBeanList.get(0);
                contractManageBean.setCreateInfo(userInfo);
                contractManageBean.setUpdateInfo(userInfo);
                contractManageBean.setContractType(contractType);
                contractManageBean.setContractStatus(ContractStatusEnum.CONTRACT_STATUS_1.getContractStatus());
                contractManageBean.setContractDate(new Date());
                int insertResult = contractManageMapper.insertContract(contractManageBean);
                if (insertResult == 0) {
                    throw new ContractException("新增普通供水合同失败！");
                }
                return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "新增合同信息成功！", String.class);
            }
            else if (ContractTypeEnum.CONTRACT_TYPE_2.getContractType().equals(contractType)) {



                MessageBean msgBean = MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "新增电子合同成功！", String.class);
                msgBean.setData("新增电子合同成功！");

                // 电子签章系统不支持批量，否则：先插入电子合同信息，如果调签章平台接口失败，抛出错误，事务回滚。（抛出错误后会回滚，事务测试无问题）
                Set<String> successUserNo = new HashSet<>();
                Set<String> failUserNo = contractManageBeanList.stream().map(o -> o.getUserNo()).collect(Collectors.toSet());
                StringBuilder failMsg = new StringBuilder("");
                String msg;
                Map<String, String> payMethod = Tools.mapDicByCode(factory, "BPW");
                Map<String, String> meterTypes = Tools.mapDicByCode(factory, "MMT");
                Map<String, String> cycle = Tools.readCycleByCode(factory);
                // 轮询调签章平台接口
                for (ContractManageBean contractManageBean : contractManageBeanList) {
                    String userNo = contractManageBean.getUserNo();
                    // 先调签章平台创建电子合同接口，成功后合同表插入数据
                    try {
                        String contractNo;
                        do {
                            contractNo = Tools.getBillNo(factory, "EC_CONTRACT", userInfo.getCurWaterCode());
                        } while (contractManageMapper.countContractNo(contractNo) > 0);

                        UserInfoVO userInfoVO = contractManageMapper.getUserInfoByUserNo(userNo);
                        if (userInfoVO == null || StringUtils.isEmpty(userInfoVO.getUserNo())) {
                            throw new ContractException("根据户号[" + userNo + "]找到的用户信息为空！");
                        }
                        // 翻译数据
                        //抄表周期
                        if (StringUtils.isNotEmpty(userInfoVO.getMeterReadingCycle())) {
                            userInfoVO.setMeterReadingCycle(cycle.get(userInfoVO.getMeterReadingCycle()));
                        }
                        //缴费方式
                        if (StringUtils.isNotEmpty(userInfoVO.getPayWay())){
                            userInfoVO.setPayWay(payMethod.get(userInfoVO.getPayWay()));
                        }
                        //水表类型
                        if (StringUtils.isNotEmpty(userInfoVO.getMeterType())){
                            userInfoVO.setMeterType(meterTypes.get(userInfoVO.getMeterType()));
                        }
                        // 通过meterBore即ID通过pub_meter_bore表找
                        String bjDN = "/";
                        String meterBoreId = userInfoVO.getMeterBore();
                        if (StringUtils.isNotEmpty(meterBoreId)) {
                            MeterBoreBean meterBoreBean = meterBoreMapper.selectMeterBoreById(meterBoreId);
                            bjDN = (meterBoreBean == null || StringUtils.isEmpty(meterBoreBean.getId()) ? "/" : String.valueOf(meterBoreBean.getBoreValue()));
                        }
                        userInfoVO.setBjDN(bjDN);

                        contractManageBean.setContractNo(contractNo);
                        userInfoVO.setContractNo(contractNo);
                        userInfoVO.setBillNo(contractManageBean.getBillNo());
                        SdkResponse<String> responseObj = ecContratService.ecContractCreat(userInfoVO, ecPeCategoryId, ecCoCategoryId,ecCompanyName);
                        // 生成电子合同成功
                        if (EcConstant.MESSAGE_SUCCESS == responseObj.getCode()) {
                            String result = responseObj.getResult();
                            Long contractId = Long.valueOf(result);
                            logger.info(userNo+"创建电子合同成功，合同ID:{}", contractId);
                            SdkResponse<DetailContract> contractDetailResponse =  ecContratService.getEcContractDetail(contractId);

                            if (Constant.MESSAGE_INT_SUCCESS != contractDetailResponse.getCode()) {
                                logger.error("用户" + userNo + "查询合同[" + contractId + "]详情失败，response ==>：" + com.koron.util.JsonUtils.objectToJson(contractDetailResponse));
                                throw new ContractException("查询合同[" + contractId + "]详情失败。");
                            }

                            contractManageBean.setCreateInfo(userInfo);
                            contractManageBean.setUpdateInfo(userInfo);
                            contractManageBean.setContractType(contractType);
                            contractManageBean.setContractStatus(ContractStatusEnum.CONTRACT_STATUS_1.getContractStatus());
                            contractManageBean.setRecordId(String.valueOf(contractId));
                            contractManageBean.setFileId(contractDetailResponse.getResult().getDocuments().get(0).getId());

                            // 如果当前用户有纸质合同，并且是签约完成、归档完成的状态，更改纸质合同状态为已作废
                            int updateContractResult = contractManageMapper.cancelPaperContract(userNo);
                            // 插进合同表
                            int insertContractResult = contractManageMapper.insertContract(contractManageBean);
                            // 更改用户表信息
                            int updateUserInfoResult = contractManageMapper.updateUserInfo(contractManageBean);

                            // 插进水司公共库
                            PubCompanyContractBean pubBean = new PubCompanyContractBean();
                            pubBean.setGroupCode(userInfo.getCurWaterCode());
                            pubBean.setUserNo(userNo);
                            pubBean.setContractNo(contractNo);
                            pubBean.setProjectId(contractManageBean.getProjectId());
                            pubBean.setRecordId(String.valueOf(contractId));
                            pubBean.setCreateInfo(userInfo);
                            pubBean.setUpdateInfo(userInfo);
                            int insertPubResult = pubCompanyContractMapper.insertCompanyContract(pubBean);
                            if (insertContractResult == 0 || updateUserInfoResult == 0 || insertPubResult == 0) {
                                String updateFailMsg = "用户[" + userNo + "]更新表数据失败：insertContractResult：" + insertContractResult + "，updateUserInfoResult："
                                        + updateUserInfoResult + "，insertPubResult：" + insertPubResult;
                                if (successUserNo.isEmpty()) {
                                    MessageBean messageBean = MessageBean.create(Constant.MESSAGE_INT_FAIL, "创建合同信息失败！", String.class);
                                    messageBean.setData(updateFailMsg);
                                    return messageBean;
                                } else {
                                    msg = "用户[" + String.join("，", successUserNo) + "]创建合同成功！<br/>用户[" + String.join("，", failUserNo) + "]创建合同失败！";
                                    msgBean.setData(msg);
                                    msgBean.setDescription(msg + updateFailMsg);
                                    return msgBean;
                                }
                            }
                            // 生成电子合同成功的用户
                            successUserNo.add(userNo);
                            // 生成电子合同失败的用户
                            failUserNo.remove(userNo);
                        } else {
                            failMsg.append("用户").append(userNo).append("新增电子合同失败：").append(responseObj.getCode())
                                    .append("，").append(responseObj.getMessage()).append("<br/>");
                            logger.error(failMsg.toString());
                        }
                    } catch (Exception e) {
                        logger.error("用户" + userNo + "创建合同失败: " + e.getMessage(), e);

                        if (successUserNo.isEmpty()) {
                            MessageBean messageBean  = MessageBean.create(Constant.MESSAGE_INT_FAIL, "新增合同信息失败! ", String.class);
                            messageBean.setData("新增合同信息失败，error: " + e.getMessage());
                            return messageBean;
                        } else {
                            msg = "用户[" + String.join("，", successUserNo) + "]创建电子合同成功！<br/>用户[" + String.join("，", failUserNo) + "]创建电子合同失败！";
                            msgBean.setData(msg);
                            msgBean.setDescription(msg + e.getMessage());
                            return msgBean;
                        }
                    }
                }
                if (StringUtils.isNotBlank(failMsg.toString())) {
                    if (successUserNo.isEmpty()) {
                         MessageBean messageBean = MessageBean.create(Constant.MESSAGE_INT_FAIL, "新增合同信息失败！", String.class);
                         messageBean.setData(failMsg.toString());
                         return messageBean;
                    } else {
                        msgBean.setData("用户[" + String.join("，", successUserNo) + "]创建电子合同成功！<br/>用户[" + String.join("，", failUserNo) + "]创建电子合同失败！");
                        msgBean.setDescription("用户[" + String.join("，", successUserNo) + "]新增电子合同成功！<br/>" + failMsg.toString());
                    }
                }
                return msgBean;
            }
        } catch (Exception e) {
            logger.error("新增合同信息失败: " + e.getMessage(), e);
            e.printStackTrace();
            MessageBean messageBean = MessageBean.create(Constant.MESSAGE_INT_FAIL, "新增合同信息失败！", String.class);
            messageBean.setData("新增合同信息失败: " + e.getMessage());
            return messageBean;
        }
        return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "新增合同信息成功！", String.class);
    }

    /**
     * 校验合同字段
     *
     * @param contractManageBeanList
     * @param contractManageMapper
     * @param userInfo
     * @return
     */
    public void checkContractManageQuery(List<ContractManageBean> contractManageBeanList, String ecPeCategoryid, String ecCoCategoryId,
                                         ContractManageMapper contractManageMapper, UserInfoBean userInfo) {

        if (CollectionUtils.isEmpty(contractManageBeanList)) {
            throw new ContractException("合同增加请求参数不能为空！");
        }
        if (userInfo == null) {
            throw new ContractException("用户信息不能为空！");
        }

        Set<String> userNos = new HashSet<>();
        for (ContractManageBean contractManageBean : contractManageBeanList) {
            String userNo = contractManageBean.getUserNo();
            String contractType = contractManageBean.getContractType();
            String contractNo = contractManageBean.getContractNo();
            String projectId = contractManageBean.getProjectId();
            String billNo = contractManageBean.getBillNo();
            if (StringUtils.isBlank(userNo)) {
                throw new ContractException("参数中的户号不能为空！");
            }
            if (userNos.contains(userNo)) {
                throw new ContractException("参数中的户号不能重复！");
            }
            userNos.add(userNo);
            if (StringUtils.isBlank(projectId)) {
                throw new ContractException("参数中的报装单ID不能为空！");
            }
            if (StringUtils.isBlank(billNo)) {
                throw new ContractException("参数中的报装单编号不能为空！");
            }
            if (StringUtils.isBlank(ecPeCategoryid) && StringUtils.isBlank(ecCoCategoryId) && ContractTypeEnum.CONTRACT_TYPE_2.getContractType().equals(contractType)) {
                throw new ContractException("不支持创建电子合同！ecPeCategoryid:" + ecPeCategoryid + "，ecCoCategoryId:" + ecCoCategoryId);
            }
            if (ContractTypeEnum.CONTRACT_TYPE_3.getContractType().equals(contractType) && StringUtils.isBlank(contractNo)) {
                throw new ContractException("普通供水合同的合同编号不能为空！");
            }

            // 普通合同
            if (ContractTypeEnum.CONTRACT_TYPE_3.getContractType().equals(contractType)) {
                int countContractNo = contractManageMapper.countContractNo(contractNo);
                if (countContractNo > 0) {
                    throw new ContractException("合同编号["+contractNo+"]重复！");
                }
                int countUserContractNo = contractManageMapper.countContract(userNo);
                if (countUserContractNo > 0) {
                    throw new ContractException("已有进行中或有效合同，如需重签请先作废旧合同！");
                }
            }

            // 电子合同
            if (ContractTypeEnum.CONTRACT_TYPE_2.getContractType().equals(contractType)) {
                int countContractNo = contractManageMapper.countEleContract(userNo);
                if (countContractNo > 0) {
                    throw new ContractException("用户["+userNo+"]已签电子合同，如需重签请先作废旧合同！");
                }
            }
        }
    }

}
